#tag Class
Class Tile
Implements TileActions,Rotateable
	#tag Method, Flags = &h0
		Function GetNorthEastSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetNorthEastSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetNorthWestSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetNorthWestSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetEastSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetEastSlot
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetSouthEastSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetSouthEastSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetSouthSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetSouthSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetWestSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetWestSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetSouthWestSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetSouthWestSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetNorthSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetNorthSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetCentreSlot() As Slot
		  // Part of the TileActions interface.
		  return state.GetCentreSlot
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub Constructor()
		  grid = new SlotGrid(self)
		  northState = new NorthIsOnTopState(self)
		  eastState = new EastIsOnTopState(self)
		  southState = new SouthIsOnTopState(self)
		  westState   = new WestIsOnTopState(self)
		  state = northState
		  top = NORTH
		  canvas = winMain.canBoard
		  canNext = winMain.canNext
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub RotateCounterClockwise()
		  // Part of the Rotateable interface.
		  if placedOnBoard = false then
		    select case top
		    case NORTH
		      state = eastState
		      top = EAST
		    case EAST
		      state = southState
		      top = SOUTH
		    case SOUTH
		      state = westState
		      top = WEST
		    case WEST
		      state = northState
		      top = NORTH
		    end select
		    
		    rotated = true
		  end if
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub RotateClockwise()
		  // Part of the Rotateable interface.
		  if placedOnBoard = false then
		    select case top
		    case NORTH
		      state = westState
		      top = WEST
		    case EAST
		      state = northState
		      top = NORTH
		    case SOUTH
		      state = eastState
		      top = EAST
		    case WEST
		      state = southState
		      top = SOUTH
		    end select
		    
		    rotated = true
		  end if
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetPossibleSides(newTile as Tile) As Sides
		  dim possibleSides as Sides
		  
		  possibleSides.north = false
		  possibleSides.east = false
		  possibleSides.south = false
		  possibleSides.west = false
		  
		  if northNeighbor = nil  and self.GetNorthSection.GetTerrainType = newTile.GetSouthSection.GetTerrainType then
		    possibleSides.north = true
		  end if
		  
		  if eastNeighbor = nil and self.GetEastSection.GetTerrainType = newTile.GetWestSection.GetTerrainType then
		    possibleSides.east = true
		  end if
		  
		  if southNeighbor = nil and self.GetSouthSection.GetTerrainType = newTile.GetNorthSection.GetTerrainType then
		    possibleSides.south = true
		  end if
		  
		  if westNeighbor = nil and self.GetWestSection.GetTerrainType = newTile.GetEastSection.GetTerrainType then
		    possibleSides.west = true
		  end if
		  
		  return possibleSides
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetNorthSection(section as TileSection)
		  if rotated = false then
		    northSection = section
		  end if
		  
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetEastSection(section as TileSection)
		  if rotated = false then
		    eastSection = section
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetSouthSection(section as TileSection)
		  if rotated = false then
		    southSection = section
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetWestSection(section as TileSection)
		  if rotated = false then
		    westSection = section
		  end if
		  
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetEastSection() As TileSection
		  return state.GetEastSection
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetNorthSection() As TileSection
		  return state.GetNorthSection
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetSouthSection() As TileSection
		  return state.GetSouthSection
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetWestSection() As TileSection
		  return state.GetWestSection
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub PlaceTile(board as GameBoard)
		  self.board = board
		  placedOnBoard = true
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetPosition(position as Coordinates)
		  if placedOnBoard = false then
		    self.position = position
		  end if
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetPosition() As Coordinates
		  return position
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetSouthNeighbor(neighbor as Tile)
		  southNeighbor = neighbor
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetNorthNeighbor(neighbor as Tile)
		  northNeighbor = neighbor
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetEastNeighbor(neighbor as Tile)
		  eastNeighbor = neighbor
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetWestNeighbor(neighbor as Tile)
		  westNeighbor = neighbor
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Function GetXRelativeToStartTile_() As integer
		  //deprecated
		  
		  'dim sX as integer
		  '
		  '//get the position of the starting Tile
		  'sX = floor((canvas.Width/medievo.TILESIZE)/2)*medievo.TILESIZE+winMain.xyScroll.x
		  '
		  'return sX + self.position.x
		  'return BoardFunctions.GetXRelativeToStartTile(self.position.x)
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub Draw()
		  dim pos as Coordinates
		  
		  pos = BoardFunctions.GetXyRelativeToStartTile(position)
		  
		  self.canvas.Graphics.ForeColor = foreColor
		  self.canvas.Graphics.FillRect (pos.x, pos.y, medievo.TILESIZE, medievo.TILESIZE)
		  self.canvas.Graphics.DrawPicture GetPicture, pos.x/app.TILESIZE * app.TILESIZE, _
		  pos.y/app.TILESIZE * app.TILESIZE, app.TILESIZE, app.TILESIZE
		  
		  
		  self.canvas.Graphics.TextSize = 16
		  
		  self.canvas.Graphics.DrawString(str(position.x) + "/" + str(position.y), pos.x +30, pos.y + 50)
		  
		  if owner <> nil then
		    self.canvas.Graphics.DrawString(owner.GetName, pos.x + 25, pos.y + 70)
		    self.canvas.Graphics.DrawString(grid.GetOccupiedType, pos.x + 25, pos.y + 90)
		  end if
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Function GetYRelativeToStartTile_() As integer
		  //deprecated
		  
		  'dim sY as integer
		  '
		  '//get the y-position of the starting Tile
		  'sY = floor((canvas.Height/medievo.TILESIZE)/2)*medievo.TILESIZE + winmain.xyScroll.y
		  '
		  'return sY - self.position.y
		  'return BoardFunctions.GetYRelativeToStartTile(self.position.y)
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetPicture() As Picture
		  return state.GetPicture
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub DrawNextTile()
		  canNext.Graphics.DrawPicture GetPicture, 0, 0, app.TILESIZE, app.TILESIZE
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub ResetPosition()
		  state = northState
		  top = NORTH
		  'rotated = false
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetAllSlots() As Dictionary
		  dim d as new Dictionary
		  
		  d.Value("nw") = GetNorthWestSlot
		  d.Value("n") = GetNorthSlot
		  d.Value("ne") = GetNorthEastSlot
		  d.Value("e") = GetEastSlot
		  d.Value("se") = GetSouthEastSlot
		  d.Value("s") = GetSouthSlot
		  d.value("sw") = GetSouthEastSlot
		  d.value("w") = GetWestSlot
		  d.Value("c") = GetCentreSlot
		  
		  return d
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetOwner() As game.Player
		  'return grid.GetOwner
		  return self.owner
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetMonasteryEstates() As game.score
		  dim score as new game.score
		  
		  if grid.GetOccupiedType = "Monastery" then
		    
		    if self.monastry = true and grid.GetIsOccupied = true then
		      if northNeighbor <> nil and northNeighbor.GetEastNeighbor <> nil and _
		        eastNeighbor <> nil and eastNeighbor.GetSouthNeighbor <> nil and _
		        southNeighbor <> nil and southNeighbor.GetWestNeighbor <> nil and _
		        westNeighbor <>  nil and westNeighbor.GetNorthNeighbor <> nil then
		        score.AddScore 9
		        score.AddOwnerColor grid.GetOwner.GetColor
		        
		      end if
		    end if
		  end if
		  
		  return score
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetNorthNeighbor() As Tile
		  return northNeighbor
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetEastNeighbor() As Tile
		  return eastNeighbor
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetSouthNeighbor() As Tile
		  return southNeighbor
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetWestNeighbor() As Tile
		  return westNeighbor
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetFinalMonasteryEstates() As game.score
		  dim score as new game.score
		  dim pos as Coordinates
		  
		  if grid.GetOccupiedType = "Monastery" then
		    
		    if self.monastry = true and grid.GetIsOccupied = true then
		      score.addscore 1
		      
		      //x..
		      //...
		      //...
		      pos.x = position.x -1
		      pos.y = position.y +1
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      //.x.
		      //...
		      //...
		      pos.x = position.x
		      pos.y = position.y +1
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      //..x
		      //...
		      //...
		      pos.x = position.x +1
		      pos.y = position.y +1
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      //...
		      //x..
		      //...
		      pos.x = position.x -1
		      pos.y = position.y
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      //...
		      //..x
		      //...
		      pos.x = position.x +1
		      pos.y = position.y
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      //...
		      //...
		      //x..
		      pos.x = position.x -1
		      pos.y = position.y -1
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      //...
		      //...
		      //.x.
		      pos.x = position.x
		      pos.y = position.y -1
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      //...
		      //...
		      //..x
		      pos.x = position.x +1
		      pos.y = position.y -1
		      
		      if board.GetTileByPosition(pos) <> nil then
		        score.addscore 1
		      end if
		      
		      
		      score.AddOwnerColor grid.GetOwner.GetColor
		    end if
		  end if
		  
		  return score
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetStreetConnections() As Connections
		  return state.GetStreetConnections
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetTownConnections() As Connections
		  return state.GetTownConnections
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetStreetConnections(sCon as connections)
		  if self.placedOnBoard = false or self.rotated = true then
		    self.StreetConnections = sCon
		  else
		    app.RaiseError (101, "Changing street-connections on tile in game", "Tile.SetStreetConnections", 3)
		  end if
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetTownConnections(tCon as Connections)
		  if self.placedOnBoard = false or self.rotated = true then
		    self.TownConnections = tCon
		  else
		    app.RaiseError (102, "Changing town-connections on tile in game", "Tile.SetTownConnections", 3)
		  end if
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetTownScore() As game.score
		  //is called for each town in the town-array in concretegame
		  //only returns a score <> 0 if the town is completed and
		  //if the owner of the tile the calculation
		  //starts owns the city (ie. either is the ownly player that owns a
		  //knight in that town or has more knights than other players)
		  
		  dim con as Connections
		  dim score as new game.score
		  dim owner as game.Player
		  dim start() as Tile
		  
		  start.Append self
		  
		  
		  owner = GetOwner
		  
		  if owner = nil then
		    exit function
		  end if
		  
		  
		  score.tiles.append self
		  
		  
		  
		  score.addOwnerColor owner.getColor
		  
		  if coatOfArms = true then
		    score.AddScore 4
		  else
		    score.AddScore 2
		  end if
		  
		  if IsSingleTown = true then
		    //special case if occupied town is a single town-tile
		    if (GetNorthSection.GetTerrainType = "Town" and northNeighbor = nil) or _
		      (GetEastSection.GetTerrainType = "Town" and eastNeighbor = nil) or _
		      (GetSouthSection.GetTerrainType = "Town" and southNeighbor = nil) or _
		      (GetWestSection.GetTerrainType = "Town" and westNeighbor = nil) then
		      return nil
		    else
		      if GetNorthSection.GetTerrainType = "Town" then
		        if GetNorthNeighbor.GetTownScore("south", score, start)= false then
		          return nil
		        end if
		        return score
		      end if
		      
		      if GetEastSection.GetTerrainType = "Town" then
		        if GetEastNeighbor.GetTownScore("west", score, start) = false then
		          return nil
		        end if
		        return score
		      end if
		      
		      
		      if GetSouthSection.GetTerrainType = "Town" then
		        if GetSouthNeighbor.GetTownScore("north", score, start) = false then
		          return nil
		        end if
		        return score
		      end if
		      
		      if GetWestSection.GetTerrainType = "Town" then
		        if GetWestNeighbor.GetTownScore("east", score, start) = false then
		          return nil
		        end if
		        return score
		      end if
		    end if
		  else
		    
		    con = GetTownConnections
		    
		    // there are open sides (ie. town could be continued
		    // in that direction but there is no neighbor
		    if con.north = true and northNeighbor = nil or _
		      con.east = true and eastNeighbor = nil or _
		      con.south = true and southNeighbor = nil or _
		      con.west = true and westNeighbor = nil then
		      'return 0
		      return nil
		    end if
		    
		    if con.north = true then
		      if GetNorthNeighbor.GetTownscore("south", score, start) = false then
		        'return 0 //the town is not finished, so no score is count
		        return nil
		      end if
		    end if
		    
		    if con.east = true then
		      if GetEastNeighbor.GetTownScore("west", score, start) = false then
		        'return 0
		        return nil
		      end if
		    end if
		    
		    if con.south = true then
		      if GetSouthNeighbor.GetTownScore("north", score, start) = false then
		        'return 0
		        return nil
		      end if
		    end if
		    
		    if con.west = true then
		      if GetWestNeighbor.GetTownScore("east", score, start) = false then
		        'return 0
		        return nil
		      end if
		    end if
		  end if
		  
		  //special case for single-towns
		  if score.getScore = 2 then
		    return nil
		  end if
		  
		  return score
		  
		  
		  
		  
		  
		  
		  
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetTownScore(comeFrom as string, score as game . score, start() as Tile) As boolean
		  dim con as Connections
		  
		  dim index as integer
		  
		  index = start.IndexOf(self)
		  
		  if index <> -1 then //we have a circle
		    exit function
		  else
		    start.Append self
		  end if
		  
		  con = GetTownConnections
		  
		  // there are open sides (ie. town could be continued
		  // in that direction but there is no neighbor
		  if con.north = true and northNeighbor = nil or _
		    con.east = true and eastNeighbor = nil or _
		    con.south = true and southNeighbor = nil or _
		    con.west = true and westNeighbor = nil then
		    return false
		  end if
		  
		  
		  if con.north = true and comeFrom <> "north" then
		    if GetNorthNeighbor.GetTownscore("south", score, start) = false then
		      return false //the town is not finished, so no score is count
		    end if
		  end if
		  
		  if con.east = true and comeFrom <> "east" then
		    if GetEastNeighbor.GetTownScore("west", score, start) = false then
		      return false
		    end if
		  end if
		  
		  if con.south = true and comeFrom <> "south" then
		    if GetSouthNeighbor.GetTownScore("north", score, start) = false then
		      return false
		    end if
		  end if
		  
		  if con.west = true and comeFrom <> "west" then
		    if GetWestNeighbor.GetTownScore("east", score, start) = false then
		      return false
		    end if
		  end if
		  
		  if GetIsOccupied = true and GetOccupiedType = "Town" then
		    score.AddOwnerColor GetOwner.getColor
		    score.tiles.append self
		  end if
		  
		  if coatOfArms = true then
		    score.AddScore 4
		  else
		    score.AddScore 2
		  end if
		  
		  return true
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetIsOccupied() As boolean
		  return grid.GetIsOccupied
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetOccupiedType() As string
		  return grid.GetOccupiedType
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetUid(s as String)
		  self.uId = s
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetUid() As string
		  return self.uId
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function SlotWizard(pos as string) As string
		  return state.SlotWizard(pos)
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetStreetScore() As game.score
		  //is called for each street in the street-array in concretegame
		  //only returns a score <> 0 if the street is completed and
		  //if the owner of the tile the calculation
		  //starts owns the street (ie. either is the ownly player that owns a
		  //highwayman on that street or has more highwaymen than other players)
		  
		  dim con as Connections
		  dim score as new game.score
		  dim owner as game.Player
		  dim start() as Tile
		  
		  start.Append self
		  
		  owner = GetOwner
		  
		  if owner = nil then
		    exit function
		  end if
		  
		  score.addOwnerColor owner.getColor
		  
		  
		  
		  score.addScore 1
		  score.tiles.append self
		  
		  
		  con = GetStreetConnections
		  
		  // there are open sides (ie. street could be continued
		  // in that direction but there is no neighbor
		  if con.north = true and northNeighbor = nil or _
		    con.east = true and eastNeighbor = nil or _
		    con.south = true and southNeighbor = nil or _
		    con.west = true and westNeighbor = nil then
		    'return 0
		    return nil
		  end if
		  
		  if con.north = true then
		    if GetNorthNeighbor.GetStreetScore("south", score, start) = false then
		      'return 0 //the town is not finished, so no score is count
		      return nil
		    end if
		  end if
		  
		  if con.east = true then
		    if GetEastNeighbor.GetStreetScore("west", score, start) = false then
		      'return 0
		      return nil
		    end if
		  end if
		  
		  if con.south = true then
		    if GetSouthNeighbor.GetStreetScore("north", score, start) = false then
		      'return 0
		      return nil
		    end if
		  end if
		  
		  if con.west = true then
		    if GetWestNeighbor.GetStreetScore("east", score, start) = false then
		      'return 0
		      return nil
		    end if
		  end if
		  
		  return score
		  
		  
		  
		  
		  
		  
		  
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetStreetScore(comeFrom as string, score as game . score, start() as Tile) As boolean
		  dim con as Connections
		  dim index as integer
		  
		  index = start.IndexOf(self)
		  
		  if index <> -1 then //we have a circle
		    exit function
		  else
		    start.Append self
		  end if
		  
		  if crossroads = false then
		    
		    
		    con = GetStreetConnections
		    
		    // there are open sides (ie. town could be continued
		    // in that direction but there is no neighbor
		    if con.north = true and northNeighbor = nil or _
		      con.east = true and eastNeighbor = nil or _
		      con.south = true and southNeighbor = nil or _
		      con.west = true and westNeighbor = nil then
		      return false
		    end if
		    
		    if con.north = true and comeFrom <> "north" then
		      if GetNorthNeighbor.GetStreetScore("south", score, start) = false then
		        return false //the town is not finished, so no score is count
		      end if
		    end if
		    
		    if con.east = true and comeFrom <> "east" then
		      if GetEastNeighbor.GetStreetScore("west", score, start) = false then
		        return false
		      end if
		    end if
		    
		    if con.south = true and comeFrom <> "south" then
		      if GetSouthNeighbor.GetStreetScore("north", score, start) = false then
		        return false
		      end if
		    end if
		    
		    if con.west = true and comeFrom <> "west" then
		      if GetWestNeighbor.GetStreetScore("east", score, start) = false then
		        return false
		      end if
		    end if
		    
		    if GetIsOccupied = true and GetOccupiedType = "Street" then
		      score.AddOwnerColor GetOwner.getColor
		      score.tiles.append self
		    end if
		  end if
		  
		  score.AddScore 1
		  
		  return true
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetIsOccupieableTown(p as game . player) As boolean
		  dim occupieable as boolean = true
		  dim con as Connections
		  dim owner as game.player
		  dim start() as Tile
		  dim occ as new OccupyCounter(p)
		  
		  
		  start.Append self
		  
		  
		  owner = GetOwner
		  if owner <> nil then
		    if owner <> occ.thePlayer then
		      return false
		    else
		      occ.add
		    end if
		  end if
		  
		  con = GetTownConnections
		  
		  if con.north = true and northNeighbor <> nil then
		    occupieable = northNeighbor.GetIsOccupieableTown("south", start, occ)
		  end if
		  
		  if con.east = true and eastNeighbor <> nil and occupieable = true then
		    occupieable = eastNeighbor.GetIsOccupieableTown("west", start, occ)
		  end if
		  
		  if con.south = true and southNeighbor <> nil and occupieable = true then
		    occupieable = southNeighbor.GetIsOccupieableTown("north", start, occ)
		  end if
		  
		  if con.west = true and westNeighbor <> nil and occupieable = true then
		    occupieable = westNeighbor.GetIsOccupieableTown("east", start, occ)
		  end if
		  
		  
		  if occupieable = true and occ.GetCnt = 1 then
		    return true
		  else
		    return false
		  end if
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetIsOccupieableStreet(p as game . player) As boolean
		  dim occupieable as boolean = true
		  dim con as Connections
		  dim owner as game.player
		  dim start() as Tile
		  
		  start.Append self
		  
		  
		  owner = GetOwner
		  if owner <> nil then
		    if owner <> p then
		      return false
		    end if
		  end if
		  
		  
		  con = GetStreetConnections
		  
		  if con.north = true and northNeighbor <> nil then
		    occupieable = northNeighbor.GetIsOccupieableStreet("south", start, p)
		  end if
		  
		  if con.east = true and eastNeighbor <> nil and occupieable = true then
		    occupieable = eastNeighbor.GetIsOccupieableStreet("west", start, p)
		  end if
		  
		  if con.south = true and southNeighbor <> nil and occupieable = true then
		    occupieable = southNeighbor.GetIsOccupieableStreet("north", start, p)
		  end if
		  
		  if con.west = true and westNeighbor <> nil and occupieable = true then
		    occupieable = westNeighbor.GetIsOccupieableStreet("east", start, p)
		  end if
		  
		  return occupieable
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetIsOccupieableStreet(comeFrom as string, start() as Tile, p as game . player) As boolean
		  dim occupieable as boolean = true
		  dim con as Connections
		  dim owner as game.player
		  dim index as integer
		  
		  index = start.IndexOf(self)
		  
		  if index <> -1 then //we have a circle
		    exit function
		  else
		    start.Append self
		  end if
		  
		  owner = GetOwner
		  if owner <> nil then
		    if owner <> p then
		      return false
		    end if
		  end if
		  
		  con = GetStreetConnections
		  
		  if con.north = true and northNeighbor <> nil and comeFrom <> "north" and comeFrom <> "north" then
		    occupieable = northNeighbor.GetIsOccupieableStreet("south", start, p)
		  end if
		  
		  if con.east = true and eastNeighbor <> nil and occupieable = true and comeFrom <> "east" then
		    occupieable = eastNeighbor.GetIsOccupieableStreet("west", start, p)
		  end if
		  
		  if con.south = true and southNeighbor <> nil and occupieable = true and comeFrom <> "south" then
		    occupieable = southNeighbor.GetIsOccupieableStreet("north", start, p)
		  end if
		  
		  if con.west = true and westNeighbor <> nil and occupieable = true and comeFrom <> "west" then
		    occupieable = westNeighbor.GetIsOccupieableStreet("east", start, p)
		  end if
		  
		  return occupieable
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetIsOccupieableTown(comeFrom as string, start() as Tile, occ as OccupyCounter) As boolean
		  dim occupieable as boolean = true
		  'dim occupieable as integer
		  dim con as Connections
		  dim owner as game.player
		  dim index as integer
		  
		  
		  index = start.IndexOf(self)
		  
		  if index <> -1 then
		    return true
		  end if
		  
		  start.Append self
		  
		  owner = GetOwner
		  if owner <> nil then
		    if owner <> occ.thePlayer then
		      return false
		    else
		      occ.add
		    end if
		  end if
		  
		  con = GetTownConnections
		  
		  if con.north = true and northNeighbor <> nil and comeFrom <> "north" then
		    occupieable = northNeighbor.GetIsOccupieableTown("south", start, occ)
		  end if
		  
		  if con.east = true and eastNeighbor <> nil and occupieable = true  _
		    and comeFrom <> "east" then
		    occupieable = eastNeighbor.GetIsOccupieableTown("west", start, occ)
		  end if
		  
		  if con.south = true and southNeighbor <> nil and occupieable = true _
		    and comeFrom <> "south" then
		    occupieable = southNeighbor.GetIsOccupieableTown("north", start, occ)
		  end if
		  
		  if con.west = true and westNeighbor <> nil and occupieable = true _
		    and comeFrom <> "west" then
		    occupieable = westNeighbor.GetIsOccupieableTown("east", start, occ)
		  end if
		  
		  return occupieable
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetFinalStreetScore() As game.score
		  //is called for each street in the street-array in concretegame
		  //only returns a score <> 0 if the street is completed and
		  //if the owner of the tile the calculation
		  //starts owns the street (ie. either is the ownly player that owns a
		  //highwayman on that street or has more highwaymen than other players)
		  
		  dim con as Connections
		  dim score as new game.score
		  dim owner as game.Player
		  dim start() as Tile
		  
		  start.Append self
		  
		  
		  owner = GetOwner
		  
		  if owner = nil then
		    exit function
		  end if
		  
		  score.addOwnerColor owner.getColor
		  score.addScore 1
		  score.tiles.append self
		  
		  
		  con = GetStreetConnections
		  
		  '// there are open sides (ie. street could be continued
		  '// in that direction but there is no neighbor
		  'if con.north = true and northNeighbor = nil or _
		  'con.east = true and eastNeighbor = nil or _
		  'con.south = true and southNeighbor = nil or _
		  'con.west = true and westNeighbor = nil then
		  ''return 0
		  'return nil
		  'end if
		  
		  if con.north = true and northNeighbor <> nil then
		    GetNorthNeighbor.GetFinalStreetScore("south", score, start)
		  end if
		  
		  if con.east = true and eastNeighbor <> nil then
		    GetEastNeighbor.GetFinalStreetScore("west", score, start)
		  end if
		  
		  if con.south = true and southNeighbor <> nil then
		    GetSouthNeighbor.GetFinalStreetScore("north", score, start)
		  end if
		  
		  if con.west = true and westNeighbor <> nil then
		    GetWestNeighbor.GetFinalStreetScore("east", score, start)
		  end if
		  
		  return score
		  
		  
		  
		  
		  
		  
		  
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub GetFinalStreetScore(comeFrom as string, score as game . score, start() as Tile)
		  //is called for each street in the street-array in concretegame
		  //only returns a score <> 0 if the street is completed and
		  //if the owner of the tile the calculation
		  //starts owns the street (ie. either is the ownly player that owns a
		  //highwayman on that street or has more highwaymen than other players)
		  
		  dim con as Connections
		  dim owner as game.Player
		  dim index as integer
		  
		  index = start.IndexOf(self)
		  
		  if index <> -1 then //we have a circle
		    exit sub
		  else
		    start.Append self
		  end if
		  
		  owner = GetOwner
		  
		  if owner <> nil then
		    'exit sub
		    score.addOwnerColor owner.getColor
		  end if
		  
		  score.addScore 1
		  score.tiles.append self
		  
		  con = GetStreetConnections
		  
		  if crossroads = true then
		    exit sub
		  end if
		  
		  
		  if con.north = true and northNeighbor <> nil _
		    and comeFrom <> "north" then
		    GetNorthNeighbor.GetFinalStreetScore("south", score, start)
		  end if
		  
		  if con.east = true and eastNeighbor <> nil _
		    and comeFrom <> "east" then
		    GetEastNeighbor.GetFinalStreetScore("west", score, start)
		  end if
		  
		  if con.south = true and southNeighbor <> nil _
		    and comeFrom <> "south" then
		    GetSouthNeighbor.GetFinalStreetScore("north", score, start)
		  end if
		  
		  if con.west = true and westNeighbor <> nil _
		    and comeFrom <> "west" then
		    GetWestNeighbor.GetFinalStreetScore("east", score, start)
		  end if
		  
		  
		  
		  
		  
		  
		  
		  
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function IsSingleTown() As boolean
		  return singleTown
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetIsSingleTown(b as boolean)
		  singleTown = b
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetFinalTownScore() As game.score
		  //is called for each Town in the Town-array in concretegame
		  //only returns a score <> 0 if the Town is completed and
		  //if the owner of the tile the calculation
		  //starts owns the Town (ie. either is the ownly player that owns a
		  //highwayman on that Town or has more highwaymen than other players)
		  
		  dim con as Connections
		  dim score as new game.score
		  dim owner as game.Player
		  dim start() as Tile
		  
		  start.Append self
		  
		  
		  owner = GetOwner
		  
		  if owner = nil then
		    exit function
		  end if
		  
		  score.addOwnerColor owner.getColor
		  
		  if coatOfArms = true then
		    score.addScore 2
		  else
		    score.addScore 1
		  end if
		  
		  score.tiles.append self
		  con = GetTownConnections
		  
		  if IsSingleTown = true then
		    //special case if occupied town is a single town-tile
		    'if (GetNorthSection.GetTerrainType = "Town" and northNeighbor = nil) or _
		    '(GetEastSection.GetTerrainType = "Town" and eastNeighbor = nil) or _
		    '(GetSouthSection.GetTerrainType = "Town" and southNeighbor = nil) or _
		    '(GetWestSection.GetTerrainType = "Town" and westNeighbor = nil) then
		    'return nil
		    'else
		    if GetNorthSection.GetTerrainType = "Town" and northNeighbor <> nil then
		      GetNorthNeighbor.GetFinalTownScore("south", score, start)
		      return score
		    end if
		    
		    if GetEastSection.GetTerrainType = "Town" and eastneighbor <> nil then
		      GetEastNeighbor.GetFinalTownScore("west", score, start)
		      return score
		    end if
		    
		    if GetSouthSection.GetTerrainType = "Town" and southNeighbor <> nil then
		      GetSouthNeighbor.GetFinalTownScore("north", score, start)
		      return score
		    end if
		    
		    if GetWestSection.GetTerrainType = "Town" and westNeighbor <> nil then
		      GetWestNeighbor.GetFinalTownScore("east", score, start)
		      return score
		    end if
		    'end if
		  else
		    
		    if con.north = true and northNeighbor <> nil then
		      GetNorthNeighbor.GetFinalTownScore("south", score, start)
		    end if
		    
		    if con.east = true and eastNeighbor <> nil then
		      GetEastNeighbor.GetFinalTownScore("west", score, start)
		    end if
		    
		    if con.south = true and southNeighbor <> nil then
		      GetSouthNeighbor.GetFinalTownScore("north", score, start)
		    end if
		    
		    if con.west = true and westNeighbor <> nil then
		      GetWestNeighbor.GetFinalTownScore("east", score, start)
		    end if
		  end if
		  
		  return score
		  
		  
		  
		  
		  
		  
		  
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub GetFinalTownScore(comeFrom as string, score as game . score, start() as Tile)
		  //is called for each town in the town-array in concretegame
		  //only returns a score <> 0 if the town is completed and
		  //if the owner of the tile the calculation
		  //starts owns the town (ie. either is the ownly player that owns a
		  //highwayman on that town or has more highwaymen than other players)
		  
		  dim con as Connections
		  dim owner as game.Player
		  dim index as integer
		  
		  index = start.IndexOf(self)
		  score.tiles.append self
		  
		  if index <> -1 then //we have a circle
		    exit sub
		  else
		    start.Append self
		  end if
		  
		  owner = GetOwner
		  
		  if owner <> nil then
		    score.addOwnerColor owner.getColor
		  end if
		  
		  if coatOfArms = true then
		    score.addscore 2
		  else
		    score.addScore 1
		  end if
		  
		  if IsSingleTown = true then
		    exit sub
		  end if
		  
		  con = GettownConnections
		  
		  if con.north = true and northNeighbor <> nil  _
		    and comeFrom <> "north" then
		    GetNorthNeighbor.GetFinaltownScore("south", score, start)
		  end if
		  
		  if con.east = true and eastNeighbor <> nil _
		    and comeFrom <> "east" then
		    GetEastNeighbor.GetFinaltownScore("west", score, start)
		  end if
		  
		  if con.south = true and southNeighbor <> nil _
		    and comeFrom <> "south" then
		    GetSouthNeighbor.GetFinaltownScore("north", score, start)
		  end if
		  
		  if con.west = true and westNeighbor <> nil _
		    and comeFrom <> "west" then
		    GetWestNeighbor.GetFinaltownScore("east", score, start)
		  end if
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub SetOwner(p as game . player)
		  self.owner = p
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub RemoveOwner()
		  self.owner = nil
		  grid.FreeSlots
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetPossibleCoordinatesForTowns() As coordinates()
		  'dim coords() as Coordinates
		  'dim xy as Coordinates
		  'dim con as Connections
		  'dim owner as game.Player
		  '
		  'owner = GetOwner
		  '
		  'if owner = nil then
		  'exit function
		  'end if
		  '
		  '
		  '//special case if occupied town is a single town-tile
		  'if IsSingleTown = true then
		  '
		  'if GetNorthSection.GetTerrainType = "Town" then
		  'if GetNorthNeighbor = nil then
		  'xy.x = self.position.x
		  'xy.y = self.position.y + 1
		  'coords.Append  xy
		  'end if
		  'end if
		  '
		  'if GetEastSection.GetTerrainType = "Town" then
		  'if GetEastNeighbor = nil then
		  'xy.x = self.position.x + 1
		  'xy.y = self.position.y
		  'coords.Append xy
		  'end if
		  'end if
		  '
		  'if GetSouthSection.GetTerrainType = "Town" then
		  'if GetSouthNeighbor = nil then
		  'xy.x = self.position.x
		  'xy.y = self.position.y - 1
		  'coords.Append xy
		  'end if
		  'end if
		  '
		  'if GetWestSection.GetTerrainType = "Town" then
		  'if GetWestNeighbor = nil then
		  'xy.x = self.position.x -1
		  'xy.y = self.position.y
		  'coords.Append xy
		  'end if
		  'end if
		  'return coords
		  'end if
		  '
		  'con = GetTownConnections
		  '
		  'if con.north = true and northNeighbor = nil
		  'xy.x = self.position.x
		  'xy.y = self.position.y + 1
		  'coords.Append  xy
		  'end if
		  '
		  'if con.east = true and eastNeighbor = nil then
		  'xy.x = self.position.x + 1
		  'xy.y = self.position.y
		  'coords.Append xy
		  'end if
		  '
		  'if con.south = true and southNeighbor = nil then
		  'xy.x = self.position.x
		  'xy.y = self.position.y - 1
		  'coords.Append xy
		  'end if
		  '
		  'if con.west = true and westNeighbor = nil then
		  'xy.x = self.position.x -1
		  'xy.y = self.position.y
		  'coords.Append xy
		  'end if
		  '
		  'if con.north = true then
		  'GetNorthNeighbor.GetPossibleCoordinatesForTown("south", coords, self)
		  'end if
		  '
		  'if con.east = true then
		  'GetEastNeighbor.GetTownScore("west", score, self)
		  'end if
		  '
		  'if con.south = true then
		  'if GetSouthNeighbor.GetTownScore("north", score, self) = false then
		  ''return 0
		  'return nil
		  'end if
		  'end if
		  '
		  'if con.west = true then
		  'if GetWestNeighbor.GetTownScore("east", score, self) = false then
		  ''return 0
		  'return nil
		  'end if
		  'end if
		  '
		  '
		  '//special case for single-towns
		  'if score.getScore = 2 then
		  'return nil
		  'end if
		  '
		  'return score
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function GetOpenTownCoordsForTile(startTile As tile) As Coordinates()
		  'dim coordinates() as Coordinates
		  'dim con as Connections
		  'dim owner as game.Player
		  'dim start() as Tile
		  '
		  'start.Append self
		  '
		  'con = GetTownConnections
		  '
		  'if IsSingleTown = true then
		  '//special case if occupied town is a single town-tile
		  'if (GetNorthSection.GetTerrainType = "Town" and northNeighbor = nil) or _
		  '(GetEastSection.GetTerrainType = "Town" and eastNeighbor = nil) or _
		  '(GetSouthSection.GetTerrainType = "Town" and southNeighbor = nil) or _
		  '(GetWestSection.GetTerrainType = "Town" and westNeighbor = nil) then
		  'return nil
		  'else
		  'if GetNorthSection.GetTerrainType = "Town" then
		  'GetNorthNeighbor.GetFinalTownScore("south", score, start)
		  'return score
		  'end if
		  '
		  'if GetEastSection.GetTerrainType = "Town" then
		  'GetEastNeighbor.GetFinalTownScore("west", score, start)
		  'return score
		  'end if
		  '
		  'if GetSouthSection.GetTerrainType = "Town" then
		  'GetSouthNeighbor.GetFinalTownScore("north", score, start)
		  'return score
		  'end if
		  '
		  'if GetWestSection.GetTerrainType = "Town" then
		  'GetWestNeighbor.GetFinalTownScore("east", score, start)
		  'return score
		  'end if
		  'end if
		  'else
		  '
		  '
		  '
		  'if con.north = true and northNeighbor <> nil then
		  'GetNorthNeighbor.GetFinalTownScore("south", score, start)
		  'end if
		  '
		  'if con.east = true and eastNeighbor <> nil then
		  'GetEastNeighbor.GetFinalTownScore("west", score, start)
		  'end if
		  '
		  'if con.south = true and southNeighbor <> nil then
		  'GetSouthNeighbor.GetFinalTownScore("north", score, start)
		  'end if
		  '
		  'if con.west = true and westNeighbor <> nil then
		  'GetWestNeighbor.GetFinalTownScore("east", score, start)
		  'end if
		  'end if
		  '
		  'return score
		  
		  
		End Function
	#tag EndMethod


	#tag Property, Flags = &h0
		northSection As TileSection
	#tag EndProperty

	#tag Property, Flags = &h0
		eastSection As TileSection
	#tag EndProperty

	#tag Property, Flags = &h0
		southSection As TileSection
	#tag EndProperty

	#tag Property, Flags = &h0
		westSection As TileSection
	#tag EndProperty

	#tag Property, Flags = &h0
		grid As SlotGrid
	#tag EndProperty

	#tag Property, Flags = &h21
		Private state As TileState
	#tag EndProperty

	#tag Property, Flags = &h21
		Private northState As TileState
	#tag EndProperty

	#tag Property, Flags = &h21
		Private eastState As TileState
	#tag EndProperty

	#tag Property, Flags = &h21
		Private southState As TileState
	#tag EndProperty

	#tag Property, Flags = &h21
		Private westState As TileState
	#tag EndProperty

	#tag Property, Flags = &h21
		Private top As Integer
	#tag EndProperty

	#tag Property, Flags = &h0
		rotated As boolean = false
	#tag EndProperty

	#tag Property, Flags = &h21
		Private northNeighbor As tile
	#tag EndProperty

	#tag Property, Flags = &h21
		Private southNeighbor As tile
	#tag EndProperty

	#tag Property, Flags = &h21
		Private westNeighbor As tile
	#tag EndProperty

	#tag Property, Flags = &h21
		Private eastNeighbor As tile
	#tag EndProperty

	#tag Property, Flags = &h21
		Private placedOnBoard As boolean = false
	#tag EndProperty

	#tag Property, Flags = &h21
		Private board As GameBoard
	#tag EndProperty

	#tag Property, Flags = &h21
		Private position As Coordinates
	#tag EndProperty

	#tag Property, Flags = &h0
		northPicture As Picture
	#tag EndProperty

	#tag Property, Flags = &h0
		eastPicture As Picture
	#tag EndProperty

	#tag Property, Flags = &h0
		southPicture As Picture
	#tag EndProperty

	#tag Property, Flags = &h0
		westPicture As Picture
	#tag EndProperty

	#tag Property, Flags = &h0
		monastry As boolean = false
	#tag EndProperty

	#tag Property, Flags = &h0
		coatOfArms As boolean = false
	#tag EndProperty

	#tag Property, Flags = &h0
		crossroads As boolean = false
	#tag EndProperty

	#tag Property, Flags = &h0
		id As Integer
	#tag EndProperty

	#tag Property, Flags = &h21
		Private canvas As GameCanvas
	#tag EndProperty

	#tag Property, Flags = &h21
		Private foreColor As color = &cFF0000
	#tag EndProperty

	#tag Property, Flags = &h21
		Private canNext As Canvas
	#tag EndProperty

	#tag Property, Flags = &h0
		StreetConnections As Connections
	#tag EndProperty

	#tag Property, Flags = &h0
		TownConnections As connections
	#tag EndProperty

	#tag Property, Flags = &h21
		Private uId As String
	#tag EndProperty

	#tag Property, Flags = &h21
		Private singleTown As boolean = false
	#tag EndProperty

	#tag Property, Flags = &h21
		Private owner As game.Player
	#tag EndProperty

	#tag Property, Flags = &h0
		type As String
	#tag EndProperty


	#tag Constant, Name = NORTH, Type = Double, Dynamic = False, Default = \"1", Scope = Public
	#tag EndConstant

	#tag Constant, Name = EAST, Type = Double, Dynamic = False, Default = \"2", Scope = Public
	#tag EndConstant

	#tag Constant, Name = SOUTH, Type = Double, Dynamic = False, Default = \"3", Scope = Public
	#tag EndConstant

	#tag Constant, Name = WEST, Type = Double, Dynamic = False, Default = \"4", Scope = Public
	#tag EndConstant


	#tag ViewBehavior
		#tag ViewProperty
			Name="Name"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Index"
			Visible=true
			Group="ID"
			InitialValue="-2147483648"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Super"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Left"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Top"
			Visible=true
			Group="Position"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="rotated"
			Group="Behavior"
			InitialValue="false"
			Type="boolean"
		#tag EndViewProperty
		#tag ViewProperty
			Name="northPicture"
			Group="Behavior"
			InitialValue="0"
			Type="Picture"
		#tag EndViewProperty
		#tag ViewProperty
			Name="eastPicture"
			Group="Behavior"
			InitialValue="0"
			Type="Picture"
		#tag EndViewProperty
		#tag ViewProperty
			Name="southPicture"
			Group="Behavior"
			InitialValue="0"
			Type="Picture"
		#tag EndViewProperty
		#tag ViewProperty
			Name="westPicture"
			Group="Behavior"
			InitialValue="0"
			Type="Picture"
		#tag EndViewProperty
		#tag ViewProperty
			Name="monastry"
			Group="Behavior"
			InitialValue="false"
			Type="boolean"
		#tag EndViewProperty
		#tag ViewProperty
			Name="coatOfArms"
			Group="Behavior"
			InitialValue="false"
			Type="boolean"
		#tag EndViewProperty
		#tag ViewProperty
			Name="crossroads"
			Group="Behavior"
			InitialValue="false"
			Type="boolean"
		#tag EndViewProperty
		#tag ViewProperty
			Name="id"
			Group="Behavior"
			InitialValue="0"
			Type="Integer"
		#tag EndViewProperty
		#tag ViewProperty
			Name="type"
			Group="Behavior"
			Type="String"
			EditorType="MultiLineEditor"
		#tag EndViewProperty
	#tag EndViewBehavior
End Class
#tag EndClass
